package org.jgroups.protocols;

import org.jgroups.Header;
import org.jgroups.Global;
import org.jgroups.util.Streamable;

import java.io.*;

/**
 * @author thsieh
 * 
 */
public class FragHeader3 extends Header implements Streamable {
    public static final byte MSG=1;       // regular msg
    public static final byte MSG_STREAM =2;      // streaming msg
    public static final byte MSG_ACK =3;       // acknowledge from reciever
    public static final byte XMIT_REQ=4;  // retransmit request
    public static final byte XMIT_RSP=5;  // retransmit response (not used)
    public static final byte XMIT_INQ=6;  // Inquiry receiver's retransmit request
    public static final byte XMIT_FC =7;  // Flow control (not used)
    public long id=0;
    public int  frag_id=0;
    public int  num_frags=0;
    // mic add type which is similar to Nakack
    public byte type;
    // the number of byte for last fragment
    public int remain;


    public FragHeader3() {
    } // used for externalization

    public FragHeader3(long id, int frag_id, int num_frags) {
        this( id, frag_id, num_frags, MSG);
    }

    public FragHeader3(long id, int frag_id, int num_frags, byte type) {
        this.id=id;
        this.frag_id=frag_id;
        this.num_frags=num_frags;
        this.type = type;
    }

    public FragHeader3(long id, int frag_id, int num_frags, byte type, int remain) {
        this.id=id;
        this.frag_id=frag_id;
        this.num_frags=num_frags;
        this.type = type;
        this.remain = remain ;
    }

    public FragHeader3 copy(byte type) {
       FragHeader3 header = new FragHeader3(id, frag_id, num_frags, type, remain );
       return header;
    }

    public String toString() {
        return "[id=" + id + ", frag_id=" + frag_id + ", num_frags=" + num_frags + ", type=" + type +']';
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeLong(id);
        out.writeInt(frag_id);
        out.writeInt(num_frags);
        out.writeByte( type);
        out.writeInt( remain);
    }


    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        id=in.readLong();
        frag_id=in.readInt();
        num_frags=in.readInt();
        type = in.readByte();
        remain = in.readInt();
    }


    public void writeTo(DataOutputStream out) throws IOException {
        out.writeLong(id);
        out.writeInt(frag_id);
        out.writeInt(num_frags);
        out.writeByte( type);
        out.writeInt( remain);;
    }

    public int size() {
        return Global.LONG_SIZE + 3*Global.INT_SIZE + Global.BYTE_SIZE ;
    }

    public void readFrom(DataInputStream in) throws IOException, IllegalAccessException, InstantiationException {
        id=in.readLong();
        frag_id=in.readInt();
        num_frags=in.readInt();
        type = in.readByte();
        remain = in.readInt();
    }

}
